"""Trabajo Practico de Sistemas Paralelos y Distribuidos
   Fernando Cardozo
   Lorena Figueredo
   Federico Gonzalez
   Sergio Gonzalez

"""

from games import *
from utils import *

#______________________________________________________________________________
# El juego reversi en si.

class Reversi(Game):
    """La clase del juego. Heredamos lo que hay en Game de aima-python. Gracias
    Norvig.
    """
    state = None
    def __init__(self):
        board = [[0 for i in range(8)] for i in range(8)]
        for i in range(0,8):
            for j in range(0,8):
                board[i][j] = 0
        board[3][3] = 1
        board[3][4] = -1
        board[4][3] = -1
        board[4][4] = 1
        self.initial = Struct(utility=0, board=board, to_move=-1)
        self.state = Struct(utility=0, board=board, to_move=-1)

    def search_piv(self, tablero, color, coorx, coory):
        "Retorna una lista de pivotes"
        f = 0
        c = 0
        piv = []
        dic = {}
        for k in range(-1, 2):
            for l in range (-1, 2):
                if (k != 0) or (l != 0):
                    f = coorx + k
                    c = coory + l
                    #Para evitar que ambos indices sean cero y queden en loop infinito
                    if  ((f >= 0) and (f < 8) and (c >= 0) and (c < 8)):
                        if not (tablero[f][c] == 0) and not (tablero[f][c] == color):
                            while ((f >= 0) and (f < 8) and (c >= 0) and (c < 8)):
                                if tablero[f][c] == color:
                                    piv.append((f,c))
                                    break
                                f = f + k
                                c = c + l
        return piv
        
    def legal_moves(self, state):
        "Return a list of the allowable moves at this point."
        #aux=[]
        sucesor={}
        for i in range(0,8):
                for j in range(0,8):
                    if(self.state.board[i][j]==0):
                        pivote = self.search_piv(self.state.board,
                                                 self.state.to_move, i, j)
                        if(pivote):
                            sucesor.update({(i,j):pivote})
        return sucesor    
         
    def make_move(self, move, state):
        "Return the state that results from making a move from a state."
        new_state = Struct(utility=None, board=clonar_tablero(self.state.board), to_move=None)
        indice=0
        posicion=move.keys().pop()
        while(len(move[posicion])):

            pivote=move[posicion].pop() 
            numFilas=pivote[0] - posicion[0]
            numCol=pivote[1] - posicion[1]

            incFila = 0
            incCol = 0
            #ve la direccion hacia donde va a voltear las fichas
            if(numFilas):
                incFila = numFilas / abs(numFilas)

            if (numCol):
                incCol = numCol / abs(numCol)

            numVolteos = max(abs(numFilas), abs(numCol))
            f = posicion[0]
            c = posicion[1]
        
            for i in range(0,numVolteos):
                new_state.board[f][c]=self.state.to_move
                c += incCol
                f += incFila
        #falta
        new_state.to_move = state.to_move # OJO, QUE FALTA ESTO!!!!
        new_state.utility = self.utility(new_state, new_state.to_move)
        return new_state

    def utility(self, state, player):
        "Return the value of this final state to player."
        blancas = 0
        negras = 0
        for i in range(0, 8):
            for j in range(0, 8):
                if (state.board[i][j] == 1): # blancas
                    blancas -= 10
                elif (state.board[i][j] == -1): # negras
                    negras += 10
        resultado = blancas + negras
        if (player == 1): # blancas
            return -resultado
        else:
            return resultado

    def terminal_test(self, state):
        "Return True if this is a final state for the game."
        return not self.legal_moves(state)

    def to_move(self, state):
        "Return the player whose move it is in this state."
        state.to_move *= -1 #se cambia de jugador
        if self.legal_moves(state):
            return state.to_move
        else:
            state.to_move *= -1 # se vuelve a cambiar por que el otro jugador no puede jugar
            return state.to_move

    def display(self, state):
        "Print or otherwise display the state."
        if (state.to_move == 1):
            print 'jugador: BLANCAS'
        elif (state.to_move == -1):
            print 'jugador: NEGRAS'
        print '    0  1  2  3  4  5  6  7'
        print '--------------------------'
        for i in range(0, 8):
            print i,'|',
            for j in range (0, 8):
                if (state.board[i][j]== 0):
                    print '. ',
                elif(state.board[i][j]== 1):
                    print 'B ',
                else:
                    print 'N ',
            print "\n"
    pass

    def successors(self, state):
        "Return a list of legal (move, state) pairs."
        return [(move, self.make_move(self.legal_moves(self.state), self.state))
                for move in self.legal_moves(self.state)]

#______________________________________________________________________________
# Funciones
   
if __name__ == "__main__":
    objetoJuego = Reversi()
    print 'legal_moves'
    print objetoJuego.legal_moves(objetoJuego.state)
    nuevoestado = objetoJuego.make_move(objetoJuego.legal_moves(objetoJuego.state), objetoJuego.state)
    objetoJuego.display(objetoJuego.state)
    objetoJuego.display(nuevoestado)
    print 'Successors'
    print objetoJuego.successors(objetoJuego.state)
    print 'legal_moves'
    print objetoJuego.legal_moves(objetoJuego.state)
    print minimax_decision(objetoJuego.state, objetoJuego, 0)
    
    
